import axios from 'axios'
import {ConfigUtils} from "@/utils/ConfigUtils";
import {DialogUtils} from "@/utils/DialogUtils";
import {useUserStore} from "@/store/user";
import {SignUtils} from "@/utils/SignUtils";
import {AesUtils} from "@/utils/AesUtils";
import {INewPara} from "@/iwb/IConfig";

const REQUEST_BASE_URL = ConfigUtils.CONFIG.baseUrl;

let whiteURL = ['/wb/auth/register','/wb/auth/login', '/wb/auth/code','/wb/auth/publicKey','/wb/auth/sync/key'];
const isWhiteURL = function(url?: string): boolean {
    //return url !==undefined && whiteURL.indexOf(url) !== -1;
    return true;
}

const signData = async function (url?: string, data?: any ) {
    if(!data) return data;
    if (isWhiteURL(url)) {
        let newPara = {} as INewPara;
        newPara.encrypt = false;
        newPara.data = data;
        return data;
    } else {
        //console.warn(data);
        let newPara = {} as INewPara;
        newPara.encrypt = true;
        newPara.data = await AesUtils.AesEncrypt(JSON.stringify(data));
        //console.warn(AesUtils.AesDecrypt(newPara.data ? newPara.data : ""));
        return newPara;
    }
}

const responseData = (res: any) => {
    if (res.code !== 200 && res.code !== 201 && res.code != 204) {
        DialogUtils.showErrorBox('错误提示', res.message || 'Error');
        if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
            // to re-login
            DialogUtils.showMessageBox('确认退出', '你已经退出登录，可以按取消留在当前页面，或者重新登录！', {
                confirmButtonText: '登  录',
                cancelButtonText: '取  消',
                type: 'warning'
            }).then(() => {
                const userStore = useUserStore();
                userStore.resetToken().then(() => {
                    location.reload()
                })
            });
        } else if (res.code === 401 || res.code === 205) {
            DialogUtils.showErrorBox('温馨提示', res.message).then(() => {
                const userStore = useUserStore();
                userStore.resetToken().then(() => {
                    location.reload()
                })
            });
        }
        return Promise.reject(new Error(res.message || 'Error'))
    } else if (res.code === 204) {
        /**
         * 用户不存在，这个时候，还是放过去
         */
        return res;
    } else if (res.code === 401) {
        DialogUtils.showErrorBox('温馨提示', '请重新登录系统！').then(() => {
            const userStore = useUserStore();
            userStore.resetToken().then(() => {
                location.reload()
            })
        });
    } else if (res.code === 201) {
        DialogUtils.showMessageInfo(res.message);
        return res;
    } else {
        return res;
    }
}

// create an axios instance
const service = axios.create({
    baseURL: REQUEST_BASE_URL, // url = base url + request url
    // withCredentials: true, // send cookies when cross-domain requests
    timeout: 30000 // request timeout
})

// request interceptor
service.interceptors.request.use(
    config => {

        let method = config.method != undefined ? config.method.toLowerCase() : "";
        let data = config.data;
        if (method === 'get' || method === 'delete') {
            data = config.params;
        }
        const userStore = useUserStore();
        if(config.headers) {
            config.headers['appId'] = 'browser';
            config.headers['uuid'] = userStore.getUUID();
        }
        if (userStore.token && config.headers) {
            config.headers['Authorization'] = 'Bearer ' + userStore.token;
            config.headers['Content-Type'] = "application/json; charset=utf-8";
            if (!isWhiteURL(config.url)) {
                config.headers['appId'] = 'browser';
                config.headers['timestamp'] =  new Date().getTime();
                config.headers['nonce'] = Math.round(SignUtils.random(100000, 999999));
                config.headers['sign'] = AesUtils.sha265(SignUtils.getSortedContent(SignUtils.json2Map(data)))
            }
        }
        if (ConfigUtils.CONFIG.baseUrl.length === 0) {
            ConfigUtils.readConfig();
        }
        config.baseURL = ConfigUtils.CONFIG.baseUrl;
        return new Promise((resolve, reject) => {
            AesUtils.AesEncrypt(userStore.loginname).then((loginname: any) => {
                if (userStore.token && config.headers) {
                    config.headers['account'] = loginname;
                }
                signData(config.url, data).then((newData: any) => {
                    method === 'get' || method === 'delete' ? config.params = newData : config.data = newData;
                    resolve(config);
                }).catch(error=>{
                    console.error(error);
                    resolve(config);
                })
            }).catch(error=>{
                console.error(error);
                resolve(config);
            });
        })
    },
    error => {
        // do something with request error
        return Promise.reject(error)
    }
)

// response interceptor
service.interceptors.response.use(
    /**
     * If you want to get http information such as headers or status
     * Please return  response => response
     */

    /**
     * Determine the request status by custom code
     * Here is just an example
     * You can also judge the status by HTTP Status Code
     */
    response => {
        const res = response.data;
        if (res.data && res.data.encrypt) {
            return new Promise((resolve, reject) => {
                AesUtils.AesDecrypt(res.data.data).then(newData=>{
                    res.data = JSON.parse(newData);
                    resolve(responseData(res));
                }).catch(error=>{
                    console.warn(error);
                    reject(error)
                })
            })
        } else {
            return responseData(res);
        }
    },
    error => {
        DialogUtils.showErrorBox('网络异常', '网络异常，请联系管理员');
        return Promise.reject(error)
    }
)

export default service
